/*
 * CPsRecordCaster.cpp
 *
 *  Created on: 2018年9月1日
 *      Author: zhengboyuan
 */

#include "CPsRecordCaster.h"
#include "CLog.h"


namespace av
{

CPsRecordCaster::CPsRecordCaster():
		m_recordStore(),
		m_sink()
{

	m_recordStore.reset(av::createRecordStore(), av::destroyRecordStore);

}

CPsRecordCaster::~CPsRecordCaster()
{
	close();
}

bool CPsRecordCaster::open(const char* dbpath)
{
	CLog::info("CPsRecordCaster::open. %s\n", dbpath);

	return m_recordStore->open(dbpath);
}

void CPsRecordCaster::close()
{
	m_recordStore->close();
}

bool CPsRecordCaster::isOpen()
{
	return m_recordStore->isOpen();
}

void CPsRecordCaster::setEventSink(PsRecordCasterSink* sink)
{
	m_sink = sink;
}

int CPsRecordCaster::findRecord(const MRecordQuery& query, int offset, MRecord* records, int size)
{
	return m_recordStore->findRecord(query, offset, records, size);
}

int CPsRecordCaster::countRecord(const MRecordQuery& query)
{
	return m_recordStore->countRecord(query);
}

bool CPsRecordCaster::getRecord(int id, av::MRecord& record)
{
	return m_recordStore->getRecord(id, record);
}

bool CPsRecordCaster::deleteRecord(int id)
{
	return m_recordStore->deleteRecord(id);
}

int CPsRecordCaster::openChannelFile(const PsRecordCasterTransport& transport, MRecord* records, int size, int64_t offset, double scale)
{
	if (!records || size <= 0)
	{
		return -1;
	}

	PsRecordCasterChannelPtr channel(new PsRecordCasterChannel());
	channel->setSink(this);

	if (!channel->open(transport, records, size, offset, scale))
	{
		return -1;
	}

	int idx = m_channels.put(channel);
	channel->setID(idx);
	return idx;
}

int CPsRecordCaster::openChannelTime(const PsRecordCasterTransport& transport, const char* device, long fromTime, long toTime, double scale)
{
	MRecordQuery query = MRecordQuery();
	query.device = device;
	query.fromTime = fromTime;
	query.toTime = toTime;

	MRecord records[MAX_RECORD] = {0};
	int count = findRecord(query, 0, records, MAX_RECORD);
	if (count <= 0)
	{
		return -1;
	}

	int64_t offset = 0;
	MRecord& record = records[0];
	if (record.startTime < fromTime)
	{
		offset = (fromTime - record.startTime) * 1000;
	}

	return openChannelFile(transport, records, count, offset, scale);
}

void CPsRecordCaster::closeChannel(int channel)
{
	PsRecordCasterChannelPtr chl;
	m_channels.remove(channel, chl);

	if (!chl)
	{
		return;
	}

	chl->close();
}

bool CPsRecordCaster::addTarget(int channel, const char* ip, int port)
{
	CLog::info("addTarget. chl: %d, ip: %s, port: %d\n", channel, ip, port);

	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return false;
	}

	return chl->addTarget(ip, port);
}

bool CPsRecordCaster::removeTarget(int channel, const char* ip, int port)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return false;
	}

	return chl->removeTarget(ip, port);
}

void CPsRecordCaster::removeTargets(int channel)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return ;
	}

	chl->removeTargets();
}

bool CPsRecordCaster::setScale(int channel, double scale)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return false;
	}

	return chl->setScale(scale);
}

bool CPsRecordCaster::seek(int channel, int64_t offset)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return false;
	}

	return chl->seek(offset);
}

bool CPsRecordCaster::startCast(int channel)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return false;
	}

	return chl->startStream();
}

void CPsRecordCaster::stopCast(int channel)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return ;
	}

	return chl->stopStream();
}

void CPsRecordCaster::pauseCast(int channel)
{
	PsRecordCasterChannelPtr chl = m_channels.getAt(channel);
	if (!chl)
	{
		CLog::warning("no such channel: %d\n", channel);
		return ;
	}

	return chl->pauseStream();
}

void CPsRecordCaster::onCasterEvent(int channel, int event)
{
	if (!m_sink)
	{
		return;
	}

	m_sink->onCasterEvent(channel, event);
}


} /* namespace av */
